use model_graph_types::assistant::ability::{self, AssistantAbility};
use serde::{Deserialize, Serialize};

use model_graph_common::transport::rrai::{
    rrai_cloud_get, rrai_cloud_object_from_string, rrai_cloud_post, PagingResponse,
};

#[derive(Debug, Serialize, Deserialize, Clone, Copy, Default, PartialEq)]
#[serde(rename_all = "UPPERCASE")]
pub enum RobotType {
    #[default]
    API,
    RRAI,
}

#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct Robot {
    pub id: u32,
    pub user_id: Option<String>,
    pub nickname: String,
    pub avatar: Option<String>,
    pub rtype: RobotType,
    pub url: String,
    pub token_key: Option<String>,
    pub token_value: Option<String>,
    pub options: Option<String>,
    pub request_jmespath: Option<String>,
    pub response_jmespath: Option<String>,
    pub peer_id: String,
    pub name_index: Option<String>,
    pub ability: Option<String>,
    pub tags: Option<String>,
}

pub async fn device_query_robot_by_id(
    token: &String,
    _peer_id: &String,
    robot_id: u32,
) -> anyhow::Result<Robot> {
    //
    let res = rrai_cloud_get(&format!("/robot/get/{}", robot_id), token).await?;
    let robot: Robot = rrai_cloud_object_from_string(&res)?;
    Ok(robot)
}

pub async fn device_query_robot_by_ids(
    token: &String,
    robot_ids: Vec<u32>,
) -> anyhow::Result<Vec<Robot>> {
    //
    let mut res: Vec<Robot> = vec![];

    for robot_id in robot_ids {
        let response = rrai_cloud_get(&format!("/robot/get/{}", robot_id), token).await?;
        let robot: Robot = rrai_cloud_object_from_string(&response)?;
        res.push(robot);
    }
    Ok(res)
}

pub async fn device_search_robot_by_ability(
    token: &String,
    peer_id: &String,
    ability: AssistantAbility,
) -> anyhow::Result<Vec<Robot>> {
    //
    let response_str = rrai_cloud_post(
        &String::from("/robot/mysearch"),
        token,
        serde_json::to_string(&serde_json::json!({
            "page_size": 10000,
            "page": 1,
            "conditions":{}
        }))?,
    )
    .await?;

    let robots: PagingResponse<Vec<Robot>> = rrai_cloud_object_from_string(&response_str)?;
    let robots = robots.data;

    let ability_str: String = ability.try_into()?;

    Ok(robots
        .iter()
        .filter(|robot| robot.ability.is_some() && robot.ability.as_ref().unwrap() == &ability_str)
        .cloned()
        .collect::<Vec<Robot>>())
}
